package cn.oversky.eom.rule;

import cn.oversky.eom.exception.EomException;
import cn.oversky.eom.exception.EomExceptionEnumImpl;
import cn.oversky.eom.utils.PropertiesUtils;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringEscapeUtils;

import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 用于做值的校验
 * @email CorvusY@foxmail.com
 * @date 2017/4/18 14:19.
 * Now is history !
 */
public class FormValueRule implements IFormValueRule {

    public FormValueRule() {
        super();
    }


    public static void main( String[] args ) {
        String json = "{\"&quot;\":34,\"&amp;\":38,\"&#39;\":39,\"&lt;\":60,\"&gt;\":62,\"&nbsp;\":160,\"&iexcl;\":161,\"&cent;\":162,\"&pound;\":163,\"&curren;\":164,\"&yen;\":165,\"&brvbar;\":166,\"&sect;\":167,\"&uml;\":168,\"&copy;\":169,\"&ordf;\":170,\"&laquo;\":171,\"&not;\":172,\"&shy;\":173,\"&reg;\":174,\"&macr;\":175,\"&deg;\":176,\"&plusmn;\":177,\"&sup2;\":178,\"&sup3;\":179,\"&acute;\":180,\"&micro;\":181,\"&para;\":182,\"&middot;\":183,\"&cedil;\":184,\"&sup1;\":185,\"&ordm;\":186,\"&raquo;\":187,\"&frac14;\":188,\"&frac12;\":189,\"&frac34;\":190,\"&iquest;\":191,\"&Agrave;\":192,\"&Aacute;\":193,\"&Acirc;\":194,\"&Atilde;\":195,\"&Auml;\":196,\"&Aring;\":197,\"&AElig;\":198,\"&Ccedil;\":199,\"&Egrave;\":200,\"&Eacute;\":201,\"&Ecirc;\":202,\"&Euml;\":203,\"&Igrave;\":204,\"&Iacute;\":205,\"&Icirc;\":206,\"&Iuml;\":207,\"&ETH;\":208,\"&Ntilde;\":209,\"&Ograve;\":210,\"&Oacute;\":211,\"&Ocirc;\":212,\"&Otilde;\":213,\"&Ouml;\":214,\"&times;\":215,\"&Oslash;\":216,\"&Ugrave;\":217,\"&Uacute;\":218,\"&Ucirc;\":219,\"&Uuml;\":220,\"&Yacute;\":221,\"&THORN;\":222,\"&szlig;\":223,\"&agrave;\":224,\"&aacute;\":225,\"&acirc;\":226,\"&atilde;\":227,\"&auml;\":228,\"&aring;\":229,\"&aelig;\":230,\"&ccedil;\":231,\"&egrave;\":232,\"&eacute;\":233,\"&ecirc;\":234,\"&euml;\":235,\"&igrave;\":236,\"&iacute;\":237,\"&icirc;\":238,\"&iuml;\":239,\"&eth;\":240,\"&ntilde;\":241,\"&ograve;\":242,\"&oacute;\":243,\"&ocirc;\":244,\"&otilde;\":245,\"&ouml;\":246,\"&divide;\":247,\"&oslash;\":248,\"&ugrave;\":249,\"&uacute;\":250,\"&ucirc;\":251,\"&uuml;\":252,\"&yacute;\":253,\"&thorn;\":254,\"&yuml;\":255,\"&OElig;\":338,\"&oelig;\":339,\"&Scaron;\":352,\"&scaron;\":353,\"&Yuml;\":376,\"&fnof;\":402,\"&circ;\":710,\"&tilde;\":732,\"&Alpha;\":913,\"&Beta;\":914,\"&Gamma;\":915,\"&Delta;\":916,\"&Epsilon;\":917,\"&Zeta;\":918,\"&Eta;\":919,\"&Theta;\":920,\"&Iota;\":921,\"&Kappa;\":922,\"&Lambda;\":923,\"&Mu;\":924,\"&Nu;\":925,\"&Xi;\":926,\"&Omicron;\":927,\"&Pi;\":928,\"&Rho;\":929,\"&Sigma;\":931,\"&Tau;\":932,\"&Upsilon;\":933,\"&Phi;\":934,\"&Chi;\":935,\"&Psi;\":936,\"&Omega;\":937,\"&alpha;\":945,\"&beta;\":946,\"&gamma;\":947,\"&delta;\":948,\"&epsilon;\":949,\"&zeta;\":950,\"&eta;\":951,\"&theta;\":952,\"&iota;\":953,\"&kappa;\":954,\"&lambda;\":955,\"&mu;\":956,\"&nu;\":957,\"&xi;\":958,\"&omicron;\":959,\"&pi;\":960,\"&rho;\":961,\"&sigmaf;\":962,\"&sigma;\":963,\"&tau;\":964,\"&upsilon;\":965,\"&phi;\":966,\"&chi;\":967,\"&psi;\":968,\"&omega;\":969,\"&thetasym;\":977,\"&upsih;\":978,\"&piv;\":982,\"&ensp;\":1194,\"&emsp;\":1195,\"&thinsp;\":1201,\"&zwnj;\":1204,\"&zwj;\":1205,\"&lrm;\":1206,\"&rlm;\":1207,\"&ndash;\":1211,\"&mdash;\":1212,\"&lsquo;\":1216,\"&rsquo;\":1217,\"&sbquo;\":1218,\"&ldquo;\":1220,\"&rdquo;\":1221,\"&bdquo;\":1222,\"&dagger;\":1224,\"&Dagger;\":1225,\"&bull;\":1226,\"&hellip;\":1230,\"&permil;\":1240,\"&prime;\":1242,\"&Prime;\":1243,\"&lsaquo;\":1249,\"&rsaquo;\":1250,\"&oline;\":1254,\"&frasl;\":1260,\"&euro;\":1364,\"&image;\":1465,\"&weierp;\":1472,\"&real;\":1476,\"&trade;\":1482,\"&alefsym;\":1501,\"&larr;\":1592,\"&uarr;\":1593,\"&rarr;\":1594,\"&darr;\":1595,\"&harr;\":1596,\"&crarr;\":1629,\"&lArr;\":1656,\"&uArr;\":1657,\"&rArr;\":1658,\"&dArr;\":1659,\"&hArr;\":1660,\"&forall;\":1704,\"&part;\":1706,\"&exist;\":1707,\"&empty;\":1709,\"&nabla;\":1711,\"&isin;\":1712,\"&notin;\":1713,\"&ni;\":1715,\"&prod;\":1719,\"&sum;\":1721,\"&minus;\":1722,\"&lowast;\":1727,\"&radic;\":1730,\"&prop;\":1733,\"&infin;\":1734,\"&ang;\":1736,\"&and;\":1743,\"&or;\":1744,\"&cap;\":1745,\"&cup;\":1746,\"&int;\":1747,\"&there4;\":1756,\"&sim;\":1764,\"&cong;\":1773,\"&asymp;\":1776,\"&ne;\":1800,\"&equiv;\":1801,\"&le;\":1804,\"&ge;\":1805,\"&sub;\":1834,\"&sup;\":1835,\"&nsub;\":1836,\"&sube;\":1838,\"&supe;\":1839,\"&oplus;\":1853,\"&otimes;\":1855,\"&perp;\":1869,\"&sdot;\":1901,\"&lceil;\":1968,\"&rceil;\":1969,\"&lfloor;\":1970,\"&rfloor;\":1971,\"&lang;\":2001,\"&rang;\":2002,\"&loz;\":2674,\"&spades;\":2824,\"&clubs;\":2827,\"&hearts;\":2829,\"&diams;\":2830}";
        Map parse = JSON.parseObject(json, Map.class);
        Set<String> set = parse.keySet();
        for( String key : set ) {
            parse.put( key , StringEscapeUtils.unescapeHtml4(key ));
        }

        System.out.println( JSON.toJSONString(parse) );
    }

    public FormValueRule(String reg, String message) {
        this.reg = Pattern.compile( reg );
        this.message = message;
    }

    public FormValueRule(Pattern reg, String message) {
        this.reg = reg;
        this.message = message;
    }

    public FormValueRule(boolean notNull, String nullMessage) {
        this.nullMessage = nullMessage;
        this.notNull = notNull;
    }

    public FormValueRule(Pattern reg, String message, String nullMessage, boolean notNull) {
        this.reg = reg;
        this.message = message;
        this.nullMessage = nullMessage;
        this.notNull = notNull;
    }

    public FormValueRule(String reg, String message, String nullMessage, boolean notNull) {
        this.reg = Pattern.compile( reg );
        this.message = message;
        this.nullMessage = nullMessage;
        this.notNull = notNull;
    }

    private Pattern reg;

    private String message;

    private String nullMessage;

    private boolean notNull = false;


    public void doRule( Object value, Object location ) {
        // 如果不允许为空，并且值为空，则抛处非空异常
        if( !PropertiesUtils.isNotNull(value) && notNull) {
            if( location == null ) {
                throw new EomException( EomExceptionEnumImpl.B602, nullMessage );
            } else {
                throw new EomException( EomExceptionEnumImpl.B602, nullMessage + location );
            }
        } else {
            if( PropertiesUtils.isNotNull( value ) ) {
                // 如果校验为通过，则抛出校验异常
                if( reg != null ) {
                    Matcher matcher = reg.matcher( value.toString() );
                    boolean matches = matcher.matches();
                    if( !matches ) {
                        if( location == null ) {
                            throw new EomException( EomExceptionEnumImpl.B602, message );
                        } else {
                            throw new EomException( EomExceptionEnumImpl.B602, message + location );
                        }
                    }
                }
            }
        }
    }

    public void doRule( Object value ) throws EomException {
        doRule( value, null );
    }

    @Override
    public String doRuleReturn(Object value) {
        // 如果不允许为空，并且值为空，则抛处非空异常
        if( !PropertiesUtils.isNotNull( value ) && notNull) {
            return nullMessage;
        } else {
            if( PropertiesUtils.isNotNull( value ) ) {
                // 如果校验为通过，则抛出校验异常
                if( reg != null ) {
                    Matcher matcher = reg.matcher( value.toString() );
                    boolean matches = matcher.matches();
                    if( !matches ) {
                        return message;
                    }
                }
            }
        }
        return null;
    }

    public Pattern getReg() {
        return reg;
    }

    public void setReg(Pattern reg) {
        this.reg = reg;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getNullMessage() {
        return nullMessage;
    }

    public void setNullMessage(String nullMessage) {
        this.nullMessage = nullMessage;
    }

    public boolean isNotNull() {
        return notNull;
    }

    public void setNotNull(boolean notNull) {
        this.notNull = notNull;
    }

}
